package com.jin.webvideo.controller;

import com.alibaba.fastjson.JSONObject;
import com.jin.webvideo.base.LoginHandler;
import com.jin.webvideo.base.util.CollectionsUtil;
import com.jin.webvideo.exception.DataException;
import com.jin.webvideo.exception.ParsingFailedException;
import com.jin.webvideo.externalInterfaces.PlatformSupport;
import com.jin.webvideo.externalInterfaces.entity.Filmography;
import com.jin.webvideo.externalInterfaces.entity.FilmographyInfo;
import com.jin.webvideo.base.spi.exception.InterfaceNotFoundException;
import com.jin.webvideo.util.base.URLUtil;
import com.jin.webvideo.util.entity.EntityUtil;
import com.jin.webvideo.util.base.MapBuilder;
import com.jin.webvideo.util.base.StringUtil;
import com.jin.webvideo.util.consts.ConfigConst;
import com.jin.webvideo.util.entity.VideoInfoBuilder;
import com.jin.webvideo.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
public class IndexController {
    @Autowired
    private InterfaceController interfaceController;
    @Autowired
    private ApiService apiService;
    @Autowired
    private VideoService videoService;
    @Autowired
    private ParserService parserService;
    @Autowired
    private ConfigService configService;

    @GetMapping("/")
    public String index(){
        return "forward:/index";
    }

    @GetMapping("/index")
    public String indexPage(HttpServletRequest request) throws InterfaceNotFoundException {
        Map<String, String> map = configService.configMapByGroupId(ConfigConst.FRAMEPAGE_CONFIG);
        request.setAttribute("config", map);
        request.setAttribute("searchList", apiService.listSearchApi());
        return "index";
    }

    @GetMapping("/search")
    public String search(HttpServletRequest request, String key, @RequestParam(required = false) String platform,  @RequestParam(required = false, defaultValue = "1")int page, @RequestParam(required = false, defaultValue = "20")int pageSize) throws Exception {
        if (StringUtil.isEmpty(key)){
            return "redirect:/";
        }
        String list = interfaceController.search(platform, key, null, page, pageSize).toJson();
        Map<String, String> map = configService.configMapByGroupId(ConfigConst.FRAMEPAGE_CONFIG);
        request.setAttribute("config", map);
        request.setAttribute("searchList", apiService.listSearchApi());
        request.setAttribute("list", list);
        return "search";
    }

    @GetMapping("/login")
    public String login(HttpServletRequest request, @RequestParam(defaultValue = "0", required = false) int errCode){
        request.setAttribute("msg",errCode==1?"账号或密码错误":"");
        return "login#c";
    }

    @GetMapping("/play")
    public String play(HttpServletRequest request, String platform, String docid, String tvid,  @RequestParam(required = false) String url, @RequestParam(required = false) String data, @RequestParam(required = false, defaultValue = "false") boolean isphone) throws Exception {
        Filmography filmography = null;
        if (PlatformSupport.isSupport(platform)){
            filmography = apiService.getActiveVideoInformation(platform, docid, tvid);
            videoService.addVideoInfo(filmography);
        }
        else {
            if (StringUtil.isEmpty(data)) {
                throw new DataException();
            }
            filmography = JSONObject.parseObject(data, Filmography.class);
            if (filmography.getVideoInfos().size() == 0){
                FilmographyInfo info = new VideoInfoBuilder().setUrl(url).setNumber(1).build();
                filmography.addVideoInfo(info);
            }
            FilmographyInfo info = CollectionsUtil.first(filmography.getVideoInfos(), (accept) -> accept.getUrl().equals(url));
            if ( null != info ){
                filmography.setAttrs(Filmography.ACTIVE_KEY, String.valueOf( info.getNumber() ));
            }
            filmography.setAttrs(Filmography.COUNT_KEY, String.valueOf(filmography.getVideoInfos().size()));
            filmography.setUrl(url);
        }
        Map<String, String> map = configService.configMapByGroupId(ConfigConst.FRAMEPAGE_CONFIG);
        request.setAttribute("config", map);
        HttpSession session = request.getSession();
        String director = "未知";
        if (null != filmography.getMate()) {
            director = EntityUtil.part2String(filmography.getMate().getDirector());
        }
        List<String> covers = videoService.getCover(platform, docid, tvid);

        filmography.setAttrs("cover", CollectionsUtil.random(covers));
        filmography.setAttrs("director", director);
        request.setAttribute("info", filmography);
        request.setAttribute("parsers", parserList(session, platform));
        return "play";
    }


    @GetMapping("/player")
    public String player(HttpServletRequest request, HttpSession session, @RequestParam(required = false, defaultValue = "") String url) throws IOException, ParsingFailedException {
        if (url.isEmpty()){
            return "playerEmpty#c";
        }
        String standardizedUrl = URLUtil.urlNoProtocol(url);
        String account = LoginHandler.getAccount(session);
        Long currentTime = videoService.getCurrentProgress(account, standardizedUrl);
        Map<String, Object> data = new HashMap<>();
        data.put("key", standardizedUrl);
        Map<String, Integer> segInfo = videoService.findSegInfo(standardizedUrl, account);
        data.put("videoSeg", segInfo);
        data.put("currentTime", currentTime);
        request.setAttribute("data", JSONObject.toJSONString(data));
        return "player#c";
    }

    public List<Map<String,Object>> parserList(HttpSession session, String platform) throws DataException {
        List<Map<String,Object>> list = new ArrayList<>();
        Map<String,Object> map = new HashMap<>();
        map.put("key", "解析器(AUTO)");
        map.put("val", "");
        map.put("checked", true);
        list.add(map);
        String account = LoginHandler.getAccount(session);
        if (account == null){
            return list;
        }
        List<Map<String, Object>> parserList = CollectionsUtil.convert(parserService.findParser(platform),
                accept -> new MapBuilder<String,Object>()
                .put("key", accept.getDesc())
                .put("val", accept.getMethod())
                .put("checked", false).build());
        list.addAll(parserList);
        return list;
    }
}
